package xyz.csmcool.imroom.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.ExceptionHandler;
import xyz.csmcool.imroom.entity.Rooms;
import xyz.csmcool.imroom.entity.vo.RoomSimpleVo;
import xyz.csmcool.imroom.feignclient.ChatClient;
import xyz.csmcool.imroom.mapper.RoomsMapper;
import xyz.csmcool.imroom.mapper.RoomsUserMapper;
import xyz.csmcool.imroom.service.IRoomsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import xyz.csmcool.imroom.service.IRoomsUserService;
import xyz.csmcool.imutil.ExceptionHandler.CommonException;
import xyz.csmcool.imutil.dto.LastMessageDto;
import xyz.csmcool.imutil.utils.ResultTool;
import xyz.csmcool.imutil.webVo.MyPage;
import xyz.csmcool.imutil.webVo.ResultCode;
import xyz.csmcool.imutil.webVo.ResultVo;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author csmcool
 * @since 2022-08-06
 */
@Service
@RequiredArgsConstructor
public class RoomsServiceImpl extends ServiceImpl<RoomsMapper, Rooms> implements IRoomsService {

    final RoomsMapper roomsMapper;
    final ChatClient chatClient;
    final IRoomsUserService roomsUserService;

    @Override
    public MyPage<Rooms> selectMyRooms(Long page, Long limit, Integer id) {
        limit = limit < 1 ? 10 : limit;
        page = page < 1 ? 0 : (page - 1) * limit;
        List<Rooms> rooms1 = roomsMapper.selectMyRooms(page, limit, id);
        MyPage<Rooms> rooms = new MyPage<>();
        rooms.setContent(rooms1);
        rooms.setTotalElements(rooms1.get(0).getTotal());
        return rooms;
    }

    @Override
    public MyPage<Rooms> selectAllRooms(Long page, Long limit) {
        limit = limit < 1 ? 10 : limit;
        page = page < 1 ? 0 : (page - 1) * limit;
        List<Rooms> rooms1 = roomsMapper.selectAllRoom(page, limit);
        MyPage<Rooms> rooms = new MyPage<>();
        rooms.setContent(rooms1);
        rooms.setTotalElements(rooms1.get(0).getTotal());
        return rooms;
    }

    @Override
    public MyPage<Rooms> searchRoom(Long page, Long limit, String name,Integer id) {
        limit = limit < 1 ? 10 : limit;
        page = page < 1 ? 0 : (page - 1) * limit;
        List<Rooms> rooms1 = roomsMapper.searchRoom(page, limit, name,id);
        MyPage<Rooms> rooms = new MyPage<>();
        rooms.setContent(rooms1);
        rooms.setTotalElements(rooms1.size() == 0 ? 0 : rooms1.get(0).getTotal());
        return rooms;
    }

    @Override
    public void deleteRoom(Integer roomId, Integer userId) {
        Boolean aBoolean = roomsMapper.deleteRoom(roomId, userId);
        if (!aBoolean) {
            throw new CommonException(ResultCode.CUSTOM_FAIL.setMessage("删除房间失败"));
        }
        chatClient.deleteRoomChats(roomId);
    }

    @Override
    public MyPage<Rooms> publicRoom(Long page, Long limit, String name, Integer sortType) {
        limit = limit < 1 ? 10 : limit;
        page = page < 1 ? 0 : (page - 1) * limit;
        List<Rooms> rooms;
        if ("default".equals(name)) {
            if (sortType == 1) {
                rooms = roomsMapper.selectAllPublicRoomByUserCountDown(page,limit);
            }else if (sortType == 2) {
                rooms = roomsMapper.selectAllPublicRoomByUserCountUp(page,limit);
            }else if (sortType == 3) {
                rooms = roomsMapper.selectAllPublicRoomByCreateTimeDown(page,limit);
            } else {
                rooms = roomsMapper.selectAllPublicRoomByCreateTimeUp(page,limit);
            }
        } else {
            rooms = roomsMapper.selectAllPublicRoomByName(page,limit,name);
        }
        MyPage<Rooms> room = new MyPage<>();
        room.setContent(rooms);
        room.setTotalElements(rooms.get(0).getTotal());
        return room;
    }

    @Override
    public MyPage<Rooms> getMyRoom(Long page, Long limit, Integer id) {
        limit = limit < 1 ? 10 : limit;
        page = page < 1 ? 0 : (page - 1) * limit;
        List<Rooms> rooms = roomsMapper.selectMyJoinRoom(page, limit, id);
        MyPage<Rooms> room = new MyPage<>();
        if(rooms.size() == 0) {
            room.setContent(new LinkedList<>());
            room.setTotalElements(0);
            return room;
        }
        room.setContent(rooms);
        room.setTotalElements(rooms.get(0).getTotal());
        return room;
    }

    @Override
    public MyPage<Rooms> searchMyRoom(Long page, Long limit, Integer id, String name) {
        limit = limit < 1 ? 10 : limit;
        page = page < 1 ? 0 : (page - 1) * limit;
        List<Rooms> rooms = roomsMapper.searchMyJoinRoom(page, limit, id, name);
        setMessage(rooms);
        MyPage<Rooms> room = new MyPage<>();
        room.setContent(rooms);
        room.setTotalElements(rooms.get(0).getTotal());
        return room;
    }

    /**
     * 查找房间信息*
     *
     * @param id
     * @return
     */
    @Override
    public RoomSimpleVo getMySimpleRoomInfo(Integer id) {
        return roomsMapper.selectOneSimpleRoom(id);
    }

    /**
     * 是否是我创建的房间
     *
     * @param id
     * @param uid
     * @return
     */
    @Override
    public Boolean isMyRoom(Integer id, Integer uid) {
        return roomsMapper.isMyRoom(id,uid) != 0;
    }

    /**
     * 创建房间
     *
     * @param rooms
     * @return
     */
    @Override
    @Transactional(rollbackFor = CommonException.class)
    public Boolean createRoom(Rooms rooms) {
        int roomId = roomsMapper.insert(rooms);
        Boolean aBoolean = roomsUserService.addOrUpdateRoomUser(rooms.getCreatedBy(), rooms.getId(), 1);
        if(roomId == 0 || !aBoolean) {
            throw new CommonException(ResultCode.CUSTOM_FAIL.setMessage("创建房间失败"));
        }
        return true;
    }

    public void setMessage(List<Rooms> rooms) {
        List<Integer> roomIds = rooms.stream().map(Rooms::getId).collect(Collectors.toList());
        roomIds.add(0);
        ResultVo<List<LastMessageDto>> lastMessage = chatClient.getLastMessage(roomIds);
        if (lastMessage.getSucceed()) {
            List<LastMessageDto> data = lastMessage.getData();
            Map<Integer, String> result1 = data.stream().collect(
                    Collectors.toMap(LastMessageDto::getId, LastMessageDto::getMessage));
            rooms.stream().forEach(item->item.setMessage(result1.get(item.getId())));
        } else {
            rooms.stream().forEach(item->item.setMessage("获取消息失败"));
        }
    }
}
